From 8ecaa09289773256564afc4c780f8ffe6946bf05 Mon Sep 17 00:00:00 2001
From: Matt Clarkson <mattc@catalyst.net.nz>
Date: Mon, 13 Jun 2011 11:17:19 +1200
Subject: [PATCH 1/2] mod/forum: Port anonymous forum posts from MDL-1071

---
 lib/messagelib.php                  |    1 +
 mod/forum/db/install.xml            |   10 ++--
 mod/forum/db/upgrade.php            |   18 +++++++
 mod/forum/lang/en/forum.php         |   25 +++++++++
 mod/forum/lib.php                   |   97 +++++++++++++++++++++++++++++------
 mod/forum/mod_form.php              |   11 ++++
 mod/forum/post.php                  |    8 +++
 mod/forum/post_form.php             |    6 ++
 mod/forum/rsslib.php                |   12 ++++-
 mod/forum/search.php                |    3 +-
 mod/forum/settings.php              |    4 +-
 mod/forum/user.php                  |    4 +-
 pix/u/anonymous.png                 |  Bin 0 -> 1007 bytes
 search/documents/forum_document.php |   11 ++--
 14 files changed, 179 insertions(+), 31 deletions(-)
 create mode 100644 pix/u/anonymous.png

diff --git a/lib/messagelib.php b/lib/messagelib.php
index 2749c18..af66f22 100644
--- a/lib/messagelib.php
+++ b/lib/messagelib.php
@@ -88,6 +88,7 @@ function message_send($eventdata) {
     $savemessage->fullmessageformat = $eventdata->fullmessageformat;
     $savemessage->fullmessagehtml   = $eventdata->fullmessagehtml;
     $savemessage->smallmessage      = $eventdata->smallmessage;
+    $savemessage->anonymous         = $eventdata->anonymous;
 
     if (!empty($eventdata->notification)) {
         $savemessage->notification = $eventdata->notification;
diff --git a/mod/forum/db/install.xml b/mod/forum/db/install.xml
index 13473f4..f337bef 100644
--- a/mod/forum/db/install.xml
+++ b/mod/forum/db/install.xml
@@ -25,8 +25,9 @@
         <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="rssarticles" NEXT="warnafter"/>
         <FIELD NAME="warnafter" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="timemodified" NEXT="blockafter"/>
         <FIELD NAME="blockafter" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="warnafter" NEXT="blockperiod"/>
-        <FIELD NAME="blockperiod" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="blockafter" NEXT="completiondiscussions"/>
-        <FIELD NAME="completiondiscussions" TYPE="int" LENGTH="9" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Nonzero if a certain number of posts are required to mark this forum completed for a user." PREVIOUS="blockperiod" NEXT="completionreplies"/>
+        <FIELD NAME="blockperiod" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="blockafter" NEXT="anonymous"/>
+        <FIELD NAME="anonymous" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="blockperiod" NEXT="completiondiscussions"/>
+        <FIELD NAME="completiondiscussions" TYPE="int" LENGTH="9" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Nonzero if a certain number of posts are required to mark this forum completed for a user." PREVIOUS="anonymous" NEXT="completionreplies"/>
         <FIELD NAME="completionreplies" TYPE="int" LENGTH="9" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Nonzero if a certain number of replies are required to mark this forum complete for a user." PREVIOUS="completiondiscussions" NEXT="completionposts"/>
         <FIELD NAME="completionposts" TYPE="int" LENGTH="9" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Nonzero if a certain number of posts or replies (total) are required to mark this forum complete for a user." PREVIOUS="completionreplies"/>
       </FIELDS>
@@ -75,7 +76,8 @@
         <FIELD NAME="messagetrust" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="messageformat" NEXT="attachment"/>
         <FIELD NAME="attachment" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false" PREVIOUS="messagetrust" NEXT="totalscore"/>
         <FIELD NAME="totalscore" TYPE="int" LENGTH="4" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="attachment" NEXT="mailnow"/>
-        <FIELD NAME="mailnow" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="totalscore"/>
+        <FIELD NAME="mailnow" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="totalscore" NEXT="anonymous"/>
+        <FIELD NAME="anonymous" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="mailnow"/>
       </FIELDS>
       <KEYS>
         <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="discussion"/>
@@ -152,4 +154,4 @@
       </INDEXES>
     </TABLE>
   </TABLES>
-</XMLDB>
\ No newline at end of file
+</XMLDB>
diff --git a/mod/forum/db/upgrade.php b/mod/forum/db/upgrade.php
index 3a56755..2b50b98 100644
--- a/mod/forum/db/upgrade.php
+++ b/mod/forum/db/upgrade.php
@@ -55,6 +55,24 @@ function xmldb_forum_upgrade($oldversion) {
         upgrade_mod_savepoint(true, 2007101511, 'forum');
     }
 
+    if ($oldversion < 2007101513) {
+        $table = new xmldb_table('forum');
+        $field = new xmldb_table('anonymous');
+        $field->setAttributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'blockperiod');
+        
+        if(!$dbman->field_exists($table,$field)) {
+            $dbman->add_field($table, $field);
+        }
+        
+        $table = new xmldb_table('forum_posts');
+        $field = new xmldb_table('anonymous');
+        $field->setAttributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'mailnow');
+    
+        if(!$dbman->field_exists($table,$field)) {
+            $dbman->add_field($table, $field);
+        }
+    }
+
     if ($oldversion < 2008072800) {
     /// Define field completiondiscussions to be added to forum
         $table = new xmldb_table('forum');
diff --git a/mod/forum/lang/en/forum.php b/mod/forum/lang/en/forum.php
index 813a696..20a8041 100755
--- a/mod/forum/lang/en/forum.php
+++ b/mod/forum/lang/en/forum.php
@@ -28,11 +28,18 @@ $string['addanewquestion'] = 'Add a new question';
 $string['addanewtopic'] = 'Add a new topic';
 $string['advancedsearch'] = 'Advanced search';
 $string['allforums'] = 'All forums';
+$string['allowanonymous'] = 'Anonymize posts?';
 $string['allowdiscussions'] = 'Can a {$a} post to this forum?';
 $string['allowsallsubscribe'] = 'This forum allows everyone to choose whether to subscribe or not';
 $string['allowsdiscussions'] = 'This forum allows each person to start one discussion topic.';
 $string['allsubscribe'] = 'Subscribe to all forums';
 $string['allunsubscribe'] = 'Unsubscribe from all forums';
+$string['anonno'] = 'No, never';
+$string['anonoptional'] = 'Optional (let the user decide)';
+$string['anonyes'] = 'Yes, all posts';
+$stinrg['anonymous'] = 'Anonymous';
+$string['anonymouspost'] = 'Post anonymously';
+$string['anonymousname'] = 'Anonymous user name';
 $string['alreadyfirstpost'] = 'This is already the first post in the discussion';
 $string['anyfile'] = 'Any file';
 $string['attachment'] = 'Attachment';
@@ -83,6 +90,7 @@ $string['completionpostshelp'] = 'requiring discussions or replies to complete';
 $string['completionreplies'] = 'Student must post replies:';
 $string['completionrepliesgroup'] = 'Require replies';
 $string['completionreplieshelp'] = 'requiring replies to complete';
+$string['configanonymousname'] = 'The user name to display on anonymous forum posts.';
 $string['configcleanreadtime'] = 'The hour of the day to clean old posts from the \'read\' table.';
 $string['configdisplaymode'] = 'The default display mode for discussions if one isn\'t set.';
 $string['configenablerssfeeds'] = 'This switch will enable the possibility of RSS feeds for all forums.  You will still need to turn feeds on manually in the settings for each forum.';
@@ -403,3 +411,20 @@ $string['yourreply'] = 'Your reply';
 $string['reference'] = 'Reference: $a';
 $string['showreplies'] = 'Show Replies';
 $string['replyfrom'] = '<a href="{$a->link}">{$a->name} wrote on {$a->date}</a>';
+$string['anonymous_help'] = '<h1>Make posts anonymous?</h1>
+
+<p><b>There are three options available:</b></p>
+
+<ul>
+ <li><b>No, never</b> (default): Anonymous posting is not an option.</li>
+ <li><b>Yes, all posts</b>: Every post n the forum will be anonymous</li>
+ <li><b>Optional</b> (let the user decide): The user will have an option to make their post anonymous. 
+</ul>
+
+<p>
+Even though anonymous posts will indeed show up as anonymous within Moodle for both instructors
+and students, the "export forum" function available to instructors will unmask anonymous posts,
+revealing the identity of the authors.  In addition, course instructors can change this forum option
+at anytime, and when changed from "Yes" or "Optional" to "No, never", all previously anonymous posts
+will be unmasked.
+</p>';
diff --git a/mod/forum/lib.php b/mod/forum/lib.php
index d77dda7..120de24 100755
--- a/mod/forum/lib.php
+++ b/mod/forum/lib.php
@@ -609,6 +609,13 @@ function forum_cron() {
                     $userfrom->customheaders[] = 'References: <moodlepost'.$post->parent.'@'.$hostname.'>';
                 }
 
+                if($forum->anonymous == 1 ? true : ($forum->anonymous == 2 ? $post->anonymous : false)) {
+                    $userto->firstname = 'Anonymous';
+                    $userto->lastname = '';
+                    $userto->email = $CFG->noreplyaddress;
+                }
+
+
                 $postsubject = "$course->shortname: ".format_string($post->subject,true);
                 $posttext = forum_make_mail_text($course, $cm, $forum, $discussion, $post, $userfrom, $userto);
                 $posthtml = forum_make_mail_html($course, $cm, $forum, $discussion, $post, $userfrom, $userto);
@@ -858,6 +865,7 @@ function forum_cron() {
 
                     foreach ($postsarray as $postid) {
                         $post = $posts[$postid];
+                        $post->anonymous = $forum->anonymous == 1 ? true : ($forum->anonymous == 2 ? $post->anonymous : false);
 
                         if (array_key_exists($post->userid, $users)) { // we might know him/her already
                             $userfrom = $users[$post->userid];
@@ -882,12 +890,16 @@ function forum_cron() {
                         if ($userto->maildigest == 2) {
                             // Subjects only
                             $by = new stdClass();
-                            $by->name = fullname($userfrom);
+                            $by->name = $post->anonymous ? $CFG->forum_anonymousname : fullname($userfrom);
                             $by->date = userdate($post->modified);
                             $posttext .= "\n".format_string($post->subject,true).' '.get_string("bynameondate", "forum", $by);
                             $posttext .= "\n---------------------------------------------------------------------";
 
-                            $by->name = "<a target=\"_blank\" href=\"$CFG->wwwroot/user/view.php?id=$userfrom->id&amp;course=$course->id\">$by->name</a>";
+                            if ($post->anonymous) {
+                                $by->name = $CFG->forum_anonymousname;
+                            } else {
+                                $by->name = "<a target=\"_blank\" href=\"$CFG->wwwroot/user/view.php?id=$userfrom->id&amp;course=$course->id\">$by->name</a>";
+                            }
                             $posthtml .= '<div><a target="_blank" href="'.$CFG->wwwroot.'/mod/forum/discuss.php?d='.$discussion->id.'#p'.$post->id.'">'.format_string($post->subject,true).'</a> '.get_string("bynameondate", "forum", $by).'</div>';
 
                         } else {
@@ -979,6 +991,8 @@ function forum_make_mail_text($course, $cm, $forum, $discussion, $post, $userfro
 
     $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
 
+    $post->anonymous = $forum->anonymous == 1 ? true : ($forum->anonymous == 2 ? $post->anonymous : false);
+
     if (!isset($userto->viewfullnames[$forum->id])) {
         $viewfullnames = has_capability('moodle/site:viewfullnames', $modcontext, $userto->id);
     } else {
@@ -992,7 +1006,7 @@ function forum_make_mail_text($course, $cm, $forum, $discussion, $post, $userfro
     }
 
     $by = New stdClass;
-    $by->name = fullname($userfrom, $viewfullnames);
+    $by->name = $post->anonymous ? $CFG->forum_anonymousname : fullname($userfrom, $viewfullnames);
     $by->date = userdate($post->modified, "", $userto->timezone);
 
     $strbynameondate = get_string('bynameondate', 'forum', $by);
@@ -1406,10 +1420,10 @@ function forum_print_recent_activity($course, $viewfullnames, $timestart) {
 
     foreach ($printposts as $post) {
         $subjectclass = empty($post->parent) ? ' bold' : '';
-
+        $fullname = $post->anonymous ? $CFG->forum_anonymousname : fullname($post, $viewfullnames);
         echo '<li><div class="head">'.
                '<div class="date">'.userdate($post->modified, $strftimerecent).'</div>'.
-               '<div class="name">'.fullname($post, $viewfullnames).'</div>'.
+               '<div class="name">'.$fullname.'</div>'.
              '</div>';
         echo '<div class="info'.$subjectclass.'">';
         if (empty($post->parent)) {
@@ -2157,6 +2171,7 @@ function forum_get_user_posts($forumid, $userid) {
                                    JOIN {user} u              ON u.id = p.userid
                              WHERE f.id = ?
                                    AND p.userid = ?
+                                   AND p.anonymous = 0
                                    $timedsql
                           ORDER BY p.modified ASC", $params);
 }
@@ -2192,6 +2207,7 @@ function forum_get_user_involved_discussions($forumid, $userid) {
                                    JOIN {forum_posts} p       ON p.discussion = d.id
                              WHERE f.id = ?
                                    AND p.userid = ?
+                                   AND p.anonymous = 0
                                    $timedsql", $params);
 }
 
@@ -2226,6 +2242,7 @@ function forum_count_user_posts($forumid, $userid) {
                                   JOIN {user} u              ON u.id = p.userid
                             WHERE f.id = ?
                                   AND p.userid = ?
+                                  AND p.anonymous = 0
                                   $timedsql", $params);
 }
 
@@ -2978,6 +2995,8 @@ function forum_make_mail_post($course, $cm, $forum, $discussion, $post, $userfro
 
     $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
 
+    $post->anonymous = $forum->anonymous == 1 ? true : ($forum->anonymous == 2 ? $post->anonymous : false);
+
     if (!isset($userto->viewfullnames[$forum->id])) {
         $viewfullnames = has_capability('moodle/site:viewfullnames', $modcontext, $userto->id);
     } else {
@@ -2991,11 +3010,12 @@ function forum_make_mail_post($course, $cm, $forum, $discussion, $post, $userfro
     $options = new stdClass();
     $options->para = true;
     $formattedtext = format_text($post->message, $post->messageformat, $options, $course->id);
+     $anonpicture = '<img alt="' . $CFG->forum_anonymousname . '" src="' . $OUTPUT->pix_url('u/anonymous') . '"/>';
 
     $output = '<table border="0" cellpadding="3" cellspacing="0" class="forumpost">';
 
     $output .= '<tr class="header"><td width="35" valign="top" class="picture left">';
-    $output .= $OUTPUT->user_picture($userfrom, array('courseid'=>$course->id));
+    $output .= $post->anonymous ? $anonpicture  : print_user_picture($userfrom, $course->id, $userfrom->picture, false, true);
     $output .= '</td>';
 
     if ($post->parent) {
@@ -3007,7 +3027,7 @@ function forum_make_mail_post($course, $cm, $forum, $discussion, $post, $userfro
 
     $fullname = fullname($userfrom, $viewfullnames);
     $by = new stdClass();
-    $by->name = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$userfrom->id.'&amp;course='.$course->id.'">'.$fullname.'</a>';
+    $by->name = $post->anonymous ? $CFG->forum_anonymousname : '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$userfrom->id.'&amp;course='.$course->id.'">'.$fullname.'</a>';
     $by->date = userdate($post->modified, '', $userto->timezone);
     $output .= '<div class="author">'.get_string('bynameondate', 'forum', $by).'</div>';
 
@@ -3115,6 +3135,7 @@ function forum_print_post($post, $discussion, $forum, &$cm, $course, $ownpost=fa
 
     $post->course = $course->id;
     $post->forum  = $forum->id;
+    $post->anonymous = $forum->anonymous == 1 ? true : ($forum->anonymous == 2 ? $post->anonymous : false);
     $post->message = file_rewrite_pluginfile_urls($post->message, 'pluginfile.php', $modcontext->id, 'mod_forum', 'post', $post->id);
 
     // caching
@@ -3200,6 +3221,7 @@ function forum_print_post($post, $discussion, $forum, &$cm, $course, $ownpost=fa
     $postuser->lastname  = $post->lastname;
     $postuser->imagealt  = $post->imagealt;
     $postuser->picture   = $post->picture;
+    $anonpicture         = '<img alt="' . $CFG->forum_anonymousname . '" src="' . $OUTPUT->pix_url('u/anonymous') . '"/>';
     $postuser->email     = $post->email;
     // Some handy things for later on
     $postuser->fullname    = fullname($postuser, $cm->cache->caps['moodle/site:viewfullnames']);
@@ -3320,7 +3342,7 @@ function forum_print_post($post, $discussion, $forum, &$cm, $course, $ownpost=fa
     $output .= html_writer::start_tag('div', array('class'=>'forumpost clearfix'.$forumpostclass.$topicclass));
     $output .= html_writer::start_tag('div', array('class'=>'row header clearfix'));
     $output .= html_writer::start_tag('div', array('class'=>'left picture'));
-    $output .= $OUTPUT->user_picture($postuser, array('courseid'=>$course->id));
+    $output .= $post->anonymous ? $anonpicture : $OUTPUT->user_picture($postuser, array('courseid'=>$course->id));
     $output .= html_writer::end_tag('div');
 
 
@@ -3333,7 +3355,11 @@ function forum_print_post($post, $discussion, $forum, &$cm, $course, $ownpost=fa
     $output .= html_writer::tag('div', $postsubject, array('class'=>'subject'));
 
     $by = new stdClass();
-    $by->name = html_writer::link($postuser->profilelink, $postuser->fullname);
+    if ($post->anonymous) {
+        $by->name = $CFG->forum_anonymousname;
+    } else {
+        $by->name = html_writer::link($postuser->profilelink, $postuser->fullname);
+    }
     $by->date = userdate($post->modified);
     $output .= html_writer::tag('div', get_string('bynameondate', 'forum', $by), array('class'=>'author'));
 
@@ -3591,11 +3617,22 @@ function forum_rating_validate($params) {
 function forum_print_discussion_header(&$post, $forum, $group=-1, $datestring="",
                                         $cantrack=true, $forumtracked=true, $canviewparticipants=true, $modcontext=NULL) {
 
-    global $USER, $CFG, $OUTPUT;
+    global $USER, $CFG, $OUTPUT, $DB;
 
     static $rowcount;
     static $strmarkalldread;
 
+    // MDL-1071
+    // Because the discussion list doesn't actually use the post to build the page we have to
+    // load each post to see if it's anonymous, but only if anonymity is optional for this forum.
+    if ($forum->anonymous == 2) {
+        $actual_post = $DB->get_record('forum_posts', array('id' => $post->id));
+        $post->anonymous = $actual_post->anonymous;
+    } else {
+        $post->anonymous = $forum->anonymous == 1 ? true : ($forum->anonymous == 2 ? $post->anonymous : false);
+    }
+
+
     if (empty($modcontext)) {
         if (!$cm = get_coursemodule_from_instance('forum', $forum->id, $forum->course)) {
             print_error('invalidcoursemodule');
@@ -3628,15 +3665,22 @@ function forum_print_discussion_header(&$post, $forum, $group=-1, $datestring=""
     $postuser->imagealt = $post->imagealt;
     $postuser->picture = $post->picture;
     $postuser->email = $post->email;
+    $anonpicture = '<img alt="' . $CFG->forum_anonymousname . '" src="' . $OUTPUT->pix_url('u/anonymous') . '"/>';
 
     echo '<td class="picture">';
-    echo $OUTPUT->user_picture($postuser, array('courseid'=>$forum->course));
+    echo $post->anonymous ? $anonpicture : $OUTPUT->user_picture($postuser, array('courseid'=>$forum->course));
     echo "</td>\n";
 
     // User name
     $fullname = fullname($post, has_capability('moodle/site:viewfullnames', $modcontext));
     echo '<td class="author">';
-    echo '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$post->userid.'&amp;course='.$forum->course.'">'.$fullname.'</a>';
+
+    if ($post->anonymous) {
+        echo $CFG->forum_anonymousname;
+    } else {
+        echo '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$post->userid.'&amp;course='.$forum->course.'">'.$fullname.'</a>';
+    }
+
     echo "</td>\n";
 
     // Group picture
@@ -3693,7 +3737,13 @@ function forum_print_discussion_header(&$post, $forum, $group=-1, $datestring=""
     $usermodified->id        = $post->usermodified;
     $usermodified->firstname = $post->umfirstname;
     $usermodified->lastname  = $post->umlastname;
-    echo '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$post->usermodified.'&amp;course='.$forum->course.'">'.
+    $lastpost = (empty($post->lastpostid)) ? $post : $DB->get_record('forum_posts', array('id' => $post->lastpostid));
+    if($lastpost->anonymous) {
+        echo $CFG->forum_anonymousname . '<br/>';
+    } else {
+        echo '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$post->usermodified.'&amp;course='.$forum->course.'">'.
+            fullname($usermodified).'</a><br/>';
+    }
          fullname($usermodified).'</a><br />';
     echo '<a href="'.$CFG->wwwroot.'/mod/forum/discuss.php?d='.$post->discussion.$parenturl.'">'.
           userdate($usedate, $datestring).'</a>';
@@ -4113,6 +4163,7 @@ function forum_add_new_post($post, $mform, &$message) {
     $post->mailed     = "0";
     $post->userid     = $USER->id;
     $post->attachment = "";
+    $post->anonymous  = $forum->anonymous == 1 ? 1 : ($forum->anonymous == 2 ? (int)$post->anonymous : 0);
 
     $post->id = $DB->insert_record("forum_posts", $post);
     $post->message = file_save_draft_area_files($post->itemid, $context->id, 'mod_forum', 'post', $post->id, array('subdirs'=>true), $post->message);
@@ -4150,6 +4201,7 @@ function forum_update_post($post, $mform, &$message) {
     $context    = get_context_instance(CONTEXT_MODULE, $cm->id);
 
     $post->modified = time();
+    $post->anonymous  = $forum->anonymous == 1 ? 1 : ($forum->anonymous == 2 ? (int)$post->anonymous : 0);
 
     $DB->update_record('forum_posts', $post);
 
@@ -4218,6 +4270,7 @@ function forum_add_discussion($discussion, $mform=null, &$message=null, $userid=
     $post->forum         = $forum->id;     // speedup
     $post->course        = $forum->course; // speedup
     $post->mailnow       = $discussion->mailnow;
+    $post->anonymous     = ($forum->anonymous == 1 ? 1 : ($forum->anonymous == 2 ? (int)$discussion->anonymous : 0));
 
     $post->id = $DB->insert_record("forum_posts", $post);
 
@@ -5563,6 +5616,13 @@ function forum_print_posts_threaded($course, &$cm, $forum, $discussion, $parent,
                 }
                 $by = new stdClass();
                 $by->name = fullname($post, $canviewfullnames);
+
+                if($post->anonymous) {
+                    $by->name = $CFG->forum_anonymousname;
+                } else {
+                    $by->name = fullname($post, $canviewfullnames);
+                }
+
                 $by->date = userdate($post->modified);
 
                 if ($forumtracked) {
@@ -5644,7 +5704,7 @@ function forum_get_recent_mod_activity(&$activities, &$index, $timestart, $cours
     $params = array($timestart, $cm->instance);
 
     if ($userid) {
-        $userselect = "AND u.id = ?";
+        $userselect = "AND u.id = ? AND p.anonymous = 0 ";
         $params[] = $userid;
     } else {
         $userselect = "";
@@ -5739,6 +5799,7 @@ function forum_get_recent_mod_activity(&$activities, &$index, $timestart, $cours
         $tmpactivity->user->picture   = $post->picture;
         $tmpactivity->user->imagealt  = $post->imagealt;
         $tmpactivity->user->email     = $post->email;
+        $tmpactivity->user->anonymous = $post->anonymous;
 
         $activities[$index++] = $tmpactivity;
     }
@@ -5762,7 +5823,11 @@ function forum_print_recent_mod_activity($activity, $courseid, $detail, $modname
     echo '<table border="0" cellpadding="3" cellspacing="0" class="forum-recent">';
 
     echo "<tr><td class=\"userpicture\" valign=\"top\">";
-    echo $OUTPUT->user_picture($activity->user, array('courseid'=>$courseid));
+    if($activity->user->anonymous) {
+        echo '<img alt="' . $CFG->forum_anonymousname . '" src="' . $OUTPUT->pix_url('u/anonymous') . '"/>';
+    } else {
+        echo $OUTPUT->user_picture($activity->user, array('courseid'=>$courseid));
+    }
     echo "</td><td class=\"$class\">";
 
     echo '<div class="title">';
@@ -5776,7 +5841,7 @@ function forum_print_recent_mod_activity($activity, $courseid, $detail, $modname
     echo '</div>';
 
     echo '<div class="user">';
-    $fullname = fullname($activity->user, $viewfullnames);
+    $fullname = $activity->user->anonymous ? $CFG->forum_anonymousname : fullname($activity->user, $viewfullnames);
     echo "<a href=\"$CFG->wwwroot/user/view.php?id={$activity->user->id}&amp;course=$courseid\">"
          ."{$fullname}</a> - ".userdate($activity->timestamp);
     echo '</div>';
diff --git a/mod/forum/mod_form.php b/mod/forum/mod_form.php
index eb2d03c..f4a08cc 100644
--- a/mod/forum/mod_form.php
+++ b/mod/forum/mod_form.php
@@ -55,6 +55,17 @@ class mod_forum_mod_form extends moodleform_mod {
 
         $this->add_intro_editor(true, get_string('forumintro', 'forum'));
 
+
+        $options = array();
+        $options[0] = get_string('anonno', 'forum');
+        $options[1] = get_string('anonyes', 'forum');
+        $options[2] = get_string('anonoptional', 'forum');
+        $mform->addElement('select', 'anonymous', get_string('allowanonymous', 'forum'), $options);
+
+        $mform->setHelpButton('anonymous', array('anonymous', get_string('allowanonymous', 'forum'), 'forum'));
+        $mform->addElement('html', '<br><center><b><em><small>Anonymous posts are not truly anonymous -- the instructor can reveal the authors\' names at any time.</small></em></b></center>');
+        $mform->addElement('html', '<center><em><small>Click on the "?" icon above for further details.</small></em></center><br>');
+
         $options = array();
         $options[FORUM_CHOOSESUBSCRIBE] = get_string('subscriptionoptional', 'forum');
         $options[FORUM_FORCESUBSCRIBE] = get_string('subscriptionforced', 'forum');
diff --git a/mod/forum/post.php b/mod/forum/post.php
index c45aeb0..14553bd 100644
--- a/mod/forum/post.php
+++ b/mod/forum/post.php
@@ -35,6 +35,7 @@ $prune   = optional_param('prune', 0, PARAM_INT);
 $name    = optional_param('name', '', PARAM_CLEAN);
 $confirm = optional_param('confirm', 0, PARAM_INT);
 $groupid = optional_param('groupid', null, PARAM_INT);
+$isanon  = optional_param('anonymous', 0, PARAM_INT) ? true : false;
 
 $PAGE->set_url('/mod/forum/post.php', array(
         'reply' => $reply,
@@ -45,6 +46,7 @@ $PAGE->set_url('/mod/forum/post.php', array(
         'name'  => $name,
         'confirm'=>$confirm,
         'groupid'=>$groupid,
+        'isanon'=>$isanon
         ));
 //these page_params will be passed as hidden variables later in the form.
 $page_params = array('reply'=>$reply, 'forum'=>$forum, 'edit'=>$edit);
@@ -143,6 +145,7 @@ if (!empty($forum)) {      // User is starting a new discussion in a forum
     $post->subject       = '';
     $post->userid        = $USER->id;
     $post->message       = '';
+    $post->anonymous     = $isanon;
     $post->messageformat = editors_get_preferred_format();
     $post->messagetrust  = 0;
 
@@ -219,6 +222,7 @@ if (!empty($forum)) {      // User is starting a new discussion in a forum
     $post->subject     = $parent->subject;
     $post->userid      = $USER->id;
     $post->message     = '';
+    $post->anonymous   = $isanon;
 
     $post->groupid = ($discussion->groupid == -1) ? 0 : $discussion->groupid;
 
@@ -273,6 +277,7 @@ if (!empty($forum)) {      // User is starting a new discussion in a forum
     $post->edit   = $edit;
     $post->course = $course->id;
     $post->forum  = $forum->id;
+    $post->anonymous = $isanon;
     $post->groupid = ($discussion->groupid == -1) ? 0 : $discussion->groupid;
 
     $post = trusttext_pre_edit($post, 'message', $modcontext);
@@ -442,6 +447,7 @@ if (!empty($forum)) {      // User is starting a new discussion in a forum
         $newpost->id      = $post->id;
         $newpost->parent  = 0;
         $newpost->subject = $name;
+        $newpost->anonymous = $isanon;
 
         $DB->update_record("forum_posts", $newpost);
 
@@ -557,6 +563,7 @@ $mform_post->set_data(array(        'attachments'=>$draftitemid,
                                     ),
                                     'subscribe'=>$subscribe?1:0,
                                     'mailnow'=>!empty($post->mailnow),
+                                    'anonymous'=>($post->anonymous)?1:0,
                                     'userid'=>$post->userid,
                                     'parent'=>$post->parent,
                                     'discussion'=>$post->discussion,
@@ -594,6 +601,7 @@ if ($fromform = $mform_post->get_data()) {
     $fromform->itemid        = $fromform->message['itemid'];
     $fromform->messageformat = $fromform->message['format'];
     $fromform->message       = $fromform->message['text'];
+    $fromform->anonymous     = empty($fromform->anonymous) ? 0 : 1;
     // WARNING: the $fromform->message array has been overwritten, do not use it anymore!
     $fromform->messagetrust  = trusttext_trusted($modcontext);
 
diff --git a/mod/forum/post_form.php b/mod/forum/post_form.php
index b26deaf..b80244e 100644
--- a/mod/forum/post_form.php
+++ b/mod/forum/post_form.php
@@ -94,6 +94,12 @@ class mod_forum_post_form extends moodleform {
             $mform->addElement('checkbox', 'mailnow', get_string('mailnow', 'forum'));
         }
 
+        // MDL-1071
+        if ($forum->anonymous == 2) {
+            $mform->addElement('checkbox', 'anonymous', get_string('anonymouspost', 'forum'));
+        }
+
+
         if (!empty($CFG->forum_enabletimedposts) && !$post->parent && has_capability('mod/forum:viewhiddentimedposts', $coursecontext)) { // hack alert
             $mform->addElement('header', '', get_string('displayperiod', 'forum'));
 
diff --git a/mod/forum/rsslib.php b/mod/forum/rsslib.php
index 7115fe7..f23f5f9 100644
--- a/mod/forum/rsslib.php
+++ b/mod/forum/rsslib.php
@@ -215,7 +215,8 @@ function forum_rss_feed_posts_sql($forum, $cm, $newsince=0) {
                  p.message AS postmessage,
                  p.created AS postcreated,
                  p.messageformat AS postformat,
-                 p.messagetrust AS posttrust
+                 p.messagetrust AS posttrust,
+                 p.anonymous
             FROM {forum_discussions} d,
                {forum_posts} p,
                {user} u
@@ -291,7 +292,14 @@ function forum_rss_feed_contents($forum, $sql) {
             }
             $user->firstname = $rec->userfirstname;
             $user->lastname = $rec->userlastname;
-            $item->author = fullname($user);
+            $item->author = $forum->anonymous == 1 ? true : ($rec->anonymous == 2 ? $rec->anonymous : false);
+            if ($rec->anonymous) {
+                $item->author = $CFG->forum_anonymousname;
+            } else {
+                $user->firstname = $rec->userfirstname;
+                $user->lastname = $rec->userlastname;
+                $item->author = fullname($user);
+            }
             $item->pubdate = $rec->postcreated;
             if ($isdiscussion) {
                 $item->link = $CFG->wwwroot."/mod/forum/discuss.php?d=".$rec->discussionid;
diff --git a/mod/forum/search.php b/mod/forum/search.php
index 96af836..41d9305 100644
--- a/mod/forum/search.php
+++ b/mod/forum/search.php
@@ -135,6 +135,7 @@ if (!$search || $showform) {
 
 /// We need to do a search now and print results
 
+$extrasql = preg_match('/(^| )user(id)?:/', $search) ? 'AND anonymous = 0' : '';
 $searchterms = str_replace('forumid:', 'instance:', $search);
 $searchterms = explode(' ', $searchterms);
 
@@ -142,7 +143,7 @@ $searchform = forum_search_form($course, $search);
 
 $PAGE->navbar->add($strsearch, new moodle_url('/mod/forum/search.php', array('id'=>$course->id)));
 $PAGE->navbar->add(s($search, true));
-if (!$posts = forum_search_posts($searchterms, $course->id, $page*$perpage, $perpage, $totalcount)) {
+if (!$posts = forum_search_posts($searchterms, $course->id, $page*$perpage, $perpage, $totalcount, $extrasql)) {
     $PAGE->set_title($strsearchresults);
     $PAGE->set_heading($course->fullname);
     echo $OUTPUT->header();
diff --git a/mod/forum/settings.php b/mod/forum/settings.php
index d2d343e..98d2a48 100644
--- a/mod/forum/settings.php
+++ b/mod/forum/settings.php
@@ -88,4 +88,6 @@ if ($ADMIN->fulltree) {
     $settings->add(new admin_setting_configcheckbox('forum_enabletimedposts', get_string('timedposts', 'forum'),
                        get_string('configenabletimedposts', 'forum'), 0));
 }
-
+    // anonymous user name
+    $settings->add(new admin_setting_configtext('forum_anonymousname', get_string('anonymousname', 'forum'),
+                       get_string('configanonymousname', 'forum'), 'Anonymous', PARAM_TEXT));
diff --git a/mod/forum/user.php b/mod/forum/user.php
index e56910e..d74b68a 100644
--- a/mod/forum/user.php
+++ b/mod/forum/user.php
@@ -95,12 +95,12 @@ echo $OUTPUT->heading($fullname);
 switch ($mode) {
     case 'posts' :
         $searchterms = array('userid:'.$user->id);
-        $extrasql = '';
+        $extrasql = 'AND anonymous = 0';
         break;
 
     default:
         $searchterms = array('userid:'.$user->id);
-        $extrasql = 'AND p.parent = 0';
+        $extrasql = 'AND p.parent = 0 AND anonymous = 0';
         break;
 }
 
diff --git a/pix/u/anonymous.png b/pix/u/anonymous.png
new file mode 100644
index 0000000000000000000000000000000000000000..d628d6dea1261acaa1b56eb4ed8714b340ff72ce
GIT binary patch
diff --git a/search/documents/forum_document.php b/search/documents/forum_document.php
index 819704d..42e0c55 100644
--- a/search/documents/forum_document.php
+++ b/search/documents/forum_document.php
@@ -35,8 +35,8 @@ class ForumSearchDocument extends SearchDocument {
     * constructor
     * @uses $DB;
     */
-    public function __construct(&$post, $forum_id, $course_id, $itemtype, $context_id) {
-        global $DB;
+    public function __constrmct(&$post, $forum_id, $course_id, $itemtype, $context_id) {
+        global $DB, $CFG;
         
         // generic information
         $doc->docid        = $post['id'];
@@ -47,7 +47,7 @@ class ForumSearchDocument extends SearchDocument {
         $doc->title        = $post['subject'];
         
         $user = $DB->get_record('user', array('id' => $post['userid']));
-        $doc->author       = fullname($user);
+        $doc->author       = $post['anonymous'] ? $CFG->forum_anonymousname : fullname($user);
         $doc->contents     = $post['message'];
         $doc->date         = $post['created'];
         $doc->url          = forum_make_link($post['discussion'], $post['id']);
@@ -61,7 +61,7 @@ class ForumSearchDocument extends SearchDocument {
             $post['groupid'] = 0;
         }
         
-        parent::__construct($doc, $data, $course_id, $post['groupid'], $post['userid'], 'mod/'.SEARCH_TYPE_FORUM);
+       parent::__construct($doc, $data, $course_id, $post['groupid'], $post['anonymous'] ? null : $post['userid'], PATH_FOR_SEARCH_TYPE_FORUM);
     } 
 }
 
@@ -221,6 +221,7 @@ function forum_get_discussions_fast($forum_id) {
             p.discussion, 
             p.message,
             p.created,
+            p.anonymous,
             d.groupid,
             p.userid, 
             u.firstname, 
@@ -391,4 +392,4 @@ function forum_link_post_processing($title){
     return mb_convert_encoding($title, 'auto', 'UTF-8');
 }
 
-?>
\ No newline at end of file
+?>
-- 
1.7.1


From 59609d3efdad877227e27f886234ae7d8e656ac9 Mon Sep 17 00:00:00 2001
From: Chris Wharton <chrisw@catalyst.net.nz>
Date: Wed, 8 Feb 2012 18:17:49 +1300
Subject: [PATCH 2/2] MDL-1071: add backup and restore for anonymous forum posts

---
 mod/forum/backup/moodle2/backup_forum_stepslib.php |    4 ++--
 .../backup/moodle2/restore_forum_stepslib.php      |    1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/mod/forum/backup/moodle2/backup_forum_stepslib.php b/mod/forum/backup/moodle2/backup_forum_stepslib.php
index 9eb48c2..7c6dd68 100644
--- a/mod/forum/backup/moodle2/backup_forum_stepslib.php
+++ b/mod/forum/backup/moodle2/backup_forum_stepslib.php
@@ -43,7 +43,7 @@ class backup_forum_activity_structure_step extends backup_activity_structure_ste
             'assessed', 'assesstimestart', 'assesstimefinish', 'scale',
             'maxbytes', 'maxattachments', 'forcesubscribe', 'trackingtype',
             'rsstype', 'rssarticles', 'timemodified', 'warnafter',
-            'blockafter', 'blockperiod', 'completiondiscussions', 'completionreplies',
+            'blockafter', 'blockperiod', 'anonymous', 'completiondiscussions', 'completionreplies',
             'completionposts'));
 
         $discussions = new backup_nested_element('discussions');
@@ -58,7 +58,7 @@ class backup_forum_activity_structure_step extends backup_activity_structure_ste
         $post = new backup_nested_element('post', array('id'), array(
             'parent', 'userid', 'created', 'modified',
             'mailed', 'subject', 'message', 'messageformat',
-            'messagetrust', 'attachment', 'totalscore', 'mailnow'));
+            'messagetrust', 'attachment', 'totalscore', 'mailnow', 'anonymous'));
 
         $ratings = new backup_nested_element('ratings');
 
diff --git a/mod/forum/backup/moodle2/restore_forum_stepslib.php b/mod/forum/backup/moodle2/restore_forum_stepslib.php
index 17e8820..102277a 100644
--- a/mod/forum/backup/moodle2/restore_forum_stepslib.php
+++ b/mod/forum/backup/moodle2/restore_forum_stepslib.php
@@ -187,6 +187,7 @@ class restore_forum_activity_structure_step extends restore_activity_structure_s
             $sd->assessed = $forumrec->assessed;
             $sd->message  = $forumrec->intro;
             $sd->messageformat = $forumrec->introformat;
+            $sd->anonymous = $forumrec->anonymous;
             $sd->messagetrust  = true;
             $sd->mailnow  = false;
             $sdid = forum_add_discussion($sd, null, $sillybyrefvar, $this->task->get_userid());
-- 
1.7.1

